package it.tukano.swingdeco.containers;

import it.tukano.xml.XmlDoc;
import it.tukano.xml.XmlDoc.XmlNode;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Insets;
import java.awt.LayoutManager;
import java.awt.Rectangle;
import java.io.File;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;

/**
 * Usa un documento svg per stabilire posizione e dimensione dei componenti. usa il nome (getName) dei componenti
 * per determinare la rispettiva regione svg di appartenenza.
 * @author utente4
 */
public class SvgLayoutManager implements LayoutManager {
    private final Map<String, SvgRect> areas;
    private final double maxx;
    private final double maxy;

    public static class SvgRect {
        private final String id;
        private final Double x, y, width, height;

        public SvgRect(XmlNode node) {
            this.id = node.getString("id", "none").replace("_", " ");
            this.x = node.getDouble("x");
            this.y = node.getDouble("y");
            this.width = node.getDouble("width");
            this.height = node.getDouble("height");
        }

        public String getId() {
            return id;
        }

        public Double getX() {
            return x;
        }

        public Double getY() {
            return y;
        }

        public Rectangle getBounds() {
            return new Rectangle(
                    (int) Math.round(x),
                    (int) Math.round(y),
                    (int) Math.round(width),
                    (int) Math.round(height));
        }
    }

    public SvgLayoutManager(URL url) {
        this(XmlDoc.newInstance(url));
    }

    public SvgLayoutManager(File file) {
        this(XmlDoc.newInstance(file));
    }

    /**
     * Instance initializer
     */
    public SvgLayoutManager(XmlDoc doc) {
        Map<String, SvgRect> areas = new HashMap<String, SvgRect>();
        double maxx = 0;
        double maxy = 0;
        for (XmlDoc.XmlNode rectNode : doc.getRoot().listChildren("rect", true)) {
            SvgRect rect = new SvgRect(rectNode);
            areas.put(rect.getId(), rect);
            maxx = Math.max(maxx, rect.getX());
            maxy = Math.max(maxy, rect.getY());
        }
        this.areas = areas;
        this.maxx = maxx;
        this.maxy = maxy;
    }

    public void addLayoutComponent(String name, Component comp) {
    }

    public void removeLayoutComponent(Component comp) {
    }

    public Dimension preferredLayoutSize(Container parent) {
        synchronized (parent.getTreeLock()) {
            Insets insets = parent.getInsets();
            int x = insets.left;
            int y = insets.right;
            Dimension dim = new Dimension(insets.left + insets.right + (int)Math.round(maxx), insets.top + insets.bottom + (int)Math.round(maxy));
            return dim;
        }
    }

    public Dimension minimumLayoutSize(Container parent) {
        return preferredLayoutSize(parent);
    }

    public void layoutContainer(Container parent) {
        synchronized (parent.getTreeLock()) {
            Insets insets = parent.getInsets();
            int x0 = insets.left;
            int y0 = insets.right;
            Component[] components = parent.getComponents();
            for (int i = 0; i < components.length; i++) {
                Component component = components[i];
                String name = component.getName();
                SvgRect rect = areas.get(name);
                if(rect != null) {
                    Rectangle bounds = rect.getBounds();
                    bounds.translate(x0, y0);
                    component.setBounds(bounds);
                }
            }
        }
    }

    public static void main(String[] args) {
        java.awt.EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                JFrame frame = new JFrame("test");
                JPanel panel = new JPanel(new SvgLayoutManager(new File("c:\\users\\pgi\\documents\\prova.layout.svg")));
                JTextField field = new JTextField();
                field.setName("nome");
                panel.add(field);
                frame.add(panel);
                frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
                frame.setSize(400, 400);
                frame.setVisible(true);
            }
        });
    }
}
